const { WebSocketServer } = require('ws');
const { OpusEncoder } = require('@discordjs/opus');
const AsrWorkerManager = require('./asr_manager');
const TtsWorkerManager = require('./tts_manager');
const LlmWorkerManager = require('./llm_manager');
const config = require('./config');
const { CheckDeviceStatus } = require('./api');
const { v4: uuidv4 } = require('uuid');
//const wss = new WebSocketServer({host: '0.0.0.0', port: config.FrontendPort });
const wss = new WebSocketServer({ port: config.FrontendPort });

const tts_manager = new TtsWorkerManager();
const llm_manager = new LlmWorkerManager();
const asr_manager = new AsrWorkerManager();

wss.on('connection', (ws) => {
  console.log("New device connect");
  let DeviceStatus = 'unkown';
  const tts_worker = tts_manager.getWorker();
  if (!tts_worker) {
    console.error('没有可用的tts工作节点');
    ws.close();
    return;
  }

  const llm_worker = llm_manager.getWorker();
  if (!llm_worker) {
    console.error('没有可用的llm工作节点');
    ws.close();
    return;
  }

  const asr_worker = asr_manager.getWorker();
  if (!asr_worker) {
    console.error('没有可用的asr工作节点');
    ws.close();
    return;
  }

  const closeHandler = () => {
    console.log("ws close")
    ws.close();
  };

  asr_worker.on('close', closeHandler);
  tts_worker.on('close', closeHandler);
  llm_worker.on('close', closeHandler);

  const sessionId = uuidv4();
  console.log("New sessiond: ", sessionId);

  const decoder = new OpusEncoder(config.decodeSampleRate, 1);

  const tts_session = tts_worker.newSession(sessionId);
  const llm_session = llm_worker.newSession(sessionId);
  const asr_session = asr_worker.newSession(sessionId);

  //处理asr 识别返回结果
  asr_session.on('asr', (text, url) => {
    console.log("Recv ARS and Send to Llm work", JSON.stringify({ type: 'text', text, url }));
    ws.send(JSON.stringify({ type: 'stt', text, session_id: sessionId}));
    // 发送给llm 后端
    llm_session.sendJson(JSON.stringify({ type: 'asr', state: 'start', text, session_id: sessionId}));
  });

  //处理llm 识别返回结果
  llm_session.on('llm', (message) => {
    const json = JSON.parse(message);
    console.log("Recv LLM Send to Tts work:", json);
    // {"type":"llm","text":"😊","emotion":"happy","session_id":"38d00fb1"}
    //ws.send(JSON.stringify({ type: 'llm', content, emotion: "happy", session_id: sessionId}));
    // 发送给tts 后端
    tts_session.sendJson(message);
  });

  //处理tts 返回的状态结果
  tts_session.on('tts', (message) => {
    const json = JSON.parse(message);
    console.log("Recv tts work message and Send to client :", json);
    // {"type":"tts","state":"sentence_start","text":"嗨！小智在这，有什么好玩的事儿吗？","session_id":"38d00fb1"}
    //ws.send(JSON.stringify({ type: 'tts', state: 'sentence_start', text, emotion: "happy", session_id: sessionId}));
    ws.send(message, { binary: false });
  });
  //处理tts 返回的语音信息
  tts_session.on('audio', (audio_date) => {
    //const json = JSON.parse(message);
    //console.log(`Tiem:${Date.now()} Rec tts work audio and Send to client: ${audio_date.length}`);
    ws.send(audio_date, { binary: true });
  });

  // 处理客户端数据
  ws.on('message', (message, isBinary) => {
    try {
      if (isBinary) {
        DeviceStatus = "active";
        if(DeviceStatus === "active") {
          //console.log("recv binary data:", message.byteLength);
          const data = decoder.decode(message);
          asr_session.sendAudio(data);
        }
      } else {
        const json = JSON.parse(message);
        console.log("Recv Client :", json);
        if (json.type === 'listen') {
          json.session_id = sessionId;
          console.log("send to asr:", json);
          asr_session.sendJson(JSON.stringify(json));
        } else if (json.type === 'hello') {
          json.session_id = sessionId;
          json.timeStamp = Date.now();
          tts_session.sendJson(JSON.stringify(json));
          if(json.status === 'logining') {
            CheckDeviceStatus(config.ManagerUrl, json.devicetype, json.macaddr).then(result => {
              console.log("异步函数返回:", result[1]);
              json.status = result[1];
              json.userId = result[2];
              json.uuid = result[3];
              json.registerCode = result[4];
              //console.log("status: ", json.status);
              if(json.status === 'registering'){
                jsonstring = {
                    'type': 'llm',
                    'timeStamp': Date.now(),
                    'state' : 'start',
                    'cnt' : -1,
                    'session_id': sessionId,
                    'content': `设备还没有注册，请登录微信小程序AI游戏硬件，注册设备，注册码：${json.registerCode}`
                }
                message = JSON.stringify(jsonstring);
                //console.log('play vocie:', message);
                tts_session.sendJson(message);
              } else if(json.status === 'active') {
                DeviceStatus = json.status;
                console.log('DeviceStatus:', DeviceStatus);
              }
            }).catch(error => {
                console.error("发生错误:", error);
            });
          }
          ws.send(JSON.stringify(json));
        } else if (json.type === 'chat') {
          json.session_id = sessionId;
          json.timeStamp = Date.now();
          llm_session.sendJson(JSON.stringify({ type: 'asr', state: 'start', text: json.content, session_id: sessionId}));
        } else if (json.type === 'tts') {
            jsonstring = {
              'type': 'llm',
              'timeStamp': Date.now(),
              'state' : 'start',
              'cnt' : -1,
              'session_id': sessionId,
              'content': json.content
          }
          message = JSON.stringify(jsonstring);
          //console.log('play vocie:', message);
          tts_session.sendJson(message);
        } else {
          console.error('收到未知消息类型:', json.type);
        }
      }
    } catch (err) {
      console.error('处理消息时出错:', err);
    }
  });

  ws.on('close', () => {
    asr_session.finish();
    asr_worker.removeListener('close', closeHandler);
    llm_session.finish();
    llm_worker.removeListener('close', closeHandler);
    tts_session.finish();
    tts_worker.removeListener('close', closeHandler);
  });
});

wss.on('listening', () => {
  console.log('AI前端服务器正在监听端口', wss.options.port);
});